package components
{
	//import flash.display.Bitmap;
	import com.greensock.TweenMax;
	
	import flash.display.BitmapData;
	import flash.display.DisplayObject;
	import flash.display.DisplayObjectContainer;
	import flash.display.InteractiveObject;
	import flash.display.Sprite;
	import flash.display.Stage;
	import flash.events.Event;
	import flash.events.EventDispatcher;
	import flash.events.MouseEvent;
	import flash.text.TextField;
	import flash.utils.clearTimeout;
	import flash.utils.getQualifiedClassName;
	import flash.utils.setTimeout;
	
	import utils.DisplayObjectUtil;

	/**
	 * Tips
	 * @author 青竹
	 *
	 */
	[Event(name="tipsShow", type="components.TipsEvent")]
	public class Tips extends EventDispatcher
	{
		  public static var toolTips:Sprite;
		  protected var _content:*;
		  protected var target:*;
          private var _fileterAlpha:Boolean;
		  private var tweenMax:TweenMax;
		  private var _bitmapCache:BitmapData;
		  public var stopOverTime:int=1000
		  private var timer:int=-1;
		  protected var stage:Stage;
		  private var _slowActionTime:Number;
		//  public static var tipsStage:Stage;
		  /**
		   *
		   * @param obj 要显示Tips的显示对象
		   * @param text tips内容.
		   * @param filterAlpha 当obj为位图时，鼠标所在位置是透明则忽略，启用此功能有一定的性能消耗。
		   * @param stopOverTimer 鼠标停留在物件stopOverTimer毫秒后显示tips.
		   * @param auto 如果为false,鼠标悬停时不显示Tips,如果为false,stopOverTime参数无效。
		   * @param slowActionTime tips出显示时渐变时间。
		   */
          public  function Tips(obj:*,content:*,filterAlpha:Boolean=false,stopOverTime:int=0,auto:Boolean=true,slowActionTime:Number=0.5):void{
			  if(getQualifiedClassName(this)=="components::Tips"){
			      throw new Error("此乃抽象类，不得直接事例化。");
			  }
  			  target=obj;
			  this.stopOverTime=stopOverTime;
			  this.fileterAlpha=filterAlpha;
			  _content=content;
			  _auto=auto;
			  _slowActionTime=slowActionTime;
			  if(obj && obj.stage==null){
				  obj.addEventListener(Event.ADDED_TO_STAGE,onAddToStage,false,0,true);
				  obj.addEventListener(Event.REMOVED_FROM_STAGE,onAddToStage,false,0,true);
			  }else{
			      init();
			  }
		  }

		  private function onAddToStage(e:Event):void{
			  if(target){
			     target.removeEventListener(Event.ADDED_TO_STAGE,onAddToStage);
			     target.removeEventListener(Event.REMOVED_FROM_STAGE,onAddToStage);
			  }
			  if(e.type==Event.ADDED_TO_STAGE){
				  stage=target.stage;
				  init();
			  }else{
				  close();
				  stage=null;
			  }
		  }
		  private var _auto:Boolean=true;
		  private function init():void{
			  if(target == null) return ;
			  stage=target.stage;
			  if(_auto){
				     target.addEventListener(MouseEvent.MOUSE_MOVE,onMouseOver,false,0,true);
	                 target.addEventListener(MouseEvent.MOUSE_OUT,onMouseOut,false,100,true);
					// target.addEventListener(MouseEvent.MOUSE_OUT,onMouseOut,false,100,true);
			  }
              if(toolTips==null){
				   	toolTips=new Sprite();
				 	toolTips.mouseEnabled=false;
				 	toolTips.mouseChildren=false;
			  }
			  if(_content==null && target && target.hasOwnProperty("name")){
				  _content=this.target.name
				 //    draw(toolTips, ); 
			  }
			  fileterAlpha= _fileterAlpha;
		  }
		  public function shopWatch():void{
			  if(_auto){
			  	target.removeEventListener(MouseEvent.MOUSE_MOVE,onMouseOver);
			  	target.removeEventListener(MouseEvent.MOUSE_OUT,onMouseOut);
			  }
			  // target.addEventListener(MouseEvent.MOUSE_OUT,onMouseOut,false,100,true);
		  }
		  public function watch():void{
			  if(_auto){
				  target.addEventListener(MouseEvent.MOUSE_MOVE,onMouseOver);
				  target.addEventListener(MouseEvent.MOUSE_OUT,onMouseOut);
			  }
		  }
		 /**
		  * 当对象为位图时，是否过滤透明区域。
		  * <font color='#ff0000'>(有较大的内存消耗)</font>
		  * @param value
		  *
		  */
          public function set fileterAlpha(value:Boolean):void{
			 if(target==null) return;
			 _fileterAlpha=value;
             if(_fileterAlpha){
			    _bitmapCache=new BitmapData(target.width,target.height,true,0)
			    _bitmapCache.draw(target);
			 }
		  }
		  public function get fileterAlpha():Boolean{
              return _fileterAlpha;
		  }
		  public function dispose():void{
			  this.close();
			  if(target){
				  target.removeEventListener(MouseEvent.MOUSE_MOVE,onMouseOver);
				  target.removeEventListener(MouseEvent.MOUSE_OUT,onMouseOut);
				  //target.removeEventListener(MouseEvent.MOUSE_OUT,onMouseOut);
				  target.removeEventListener(Event.ADDED_TO_STAGE,onAddToStage);
			  }
//			  if(toolTips){
//			  	 toolTips.removeEventListener(Event.ADDED_TO_STAGE,onStage)
//			 	 toolTips.removeEventListener(Event.REMOVED_FROM_STAGE,onStage)
//			  }
			  stage=null;
			  target=null;
		  }
		  public var offsetX:Number=15;
		  public var offsetY:Number=15;
		  public static var platform:int;//平台
		  public static const MOBILE:int=1;//移动
		  public static const WEB:int=0;//web
		 // private var _isShow:Boolean=false;
		  protected function resetPostion():void{
			  
			  var sg:Stage=target.stage;
			  if(sg==null) return;
			  if(platform==WEB){
					  if(sg.mouseX+toolTips.width+offsetX>sg.stageWidth){
						  toolTips.x=int(sg.stageWidth-toolTips.width);
					  }else{
						  toolTips.x=int(sg.mouseX+offsetX);
					  }
					  if(sg.mouseY+toolTips.height+offsetY>sg.stageHeight){
						  toolTips.y=int(sg.stageHeight-toolTips.height);
					  }else{
						  toolTips.y=int(sg.mouseY+offsetY);
					  }
					  
			  }else{
				  
				  if(sg.mouseX+toolTips.width+offsetX>sg.stageWidth){
					  toolTips.x=int(sg.stageWidth-toolTips.width);
				  }else{
					  toolTips.x=int(sg.mouseX+offsetX)-toolTips.width/2;
				  }
				  if(sg.mouseY+toolTips.height+offsetY>sg.stageHeight){
					  toolTips.y=int(sg.stageHeight-toolTips.height);
				  }else{
					  toolTips.y=sg.mouseY-toolTips.height-offsetY;
				  }
			  }
			 if(toolTips.parent==null){
					show(toolTips);
			 }
		  }
		  
		  /**
		   * 强制显示。
		   *
		   */
		  public function force():void{
			  if(target.stage==null) return;
			  var sg:Stage=this.target.stage;
			  resetPostion();
			  if(!sg.contains(toolTips)){
				  if(stopOverTime>0){
				 	  clearTimeout(timer);
				  	  timer= setTimeout(show,stopOverTime,toolTips);
				  }else{
					  show(toolTips);
				  }
			  }
			  //if(!target.stage.hasEventListener(MouseEvent.MOUSE_MOVE)){
			  		target.stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove,false,0,true);
			  //}
		  }
		  private function onMouseMove(e:MouseEvent):void{
//			  if(target ){
//				  if(e.target != target){
//			      		close();
//						return;
//				  }
//				  if(target.hasOwnProperty("contains") && !target.contains(e.target) ){
//					  close();
//					  return;
//				  }
//			  }
			  if( !target.stage || !target.hitTestPoint( target.stage.mouseX , target.stage.mouseY )){
				  if(toolTips.stage){
					  toolTips.stage.addEventListener(MouseEvent.MOUSE_MOVE,onMouseMove,false,0,true);
				  }
			      return 
			  }
			  
			  resetPostion();
			  
		  }
		  private var _visible:Boolean=true;
		  protected function show(child:DisplayObject):void{
			  if(!_visible ) return;
			  this.dispatchEvent(new TipsEvent(TipsEvent.TIPS_SHOW) );
			  if(this.target.stage){
			  	this.target.stage.addChild(child);
			  }
			  if(toolTips){
			  	this.draw(toolTips,_content);
			  }
			  toolTips.alpha=0;
			  tweenMax=TweenMax.to(toolTips,_slowActionTime,{alpha:1})
		  }
		  protected  function onMouseOver(e:MouseEvent):void{
			   if(_fileterAlpha){
				  var pix:uint= _bitmapCache.getPixel32(target.mouseX,target.mouseY);
				  pix= pix>>24 & 0x000000ff;
                  if(pix==0){
					  close();
					  return;
				  }
			   }
			   force();
		  }
		  
		  private  function onMouseOut(e:MouseEvent):void{
			  close()
		  }
		  
          public function close():void{	
			  if(stage==null) return;
//			  if( !_isShow) return;
//			  _isShow=false;
			  clearTimeout(timer);
			  if(stage.contains(toolTips)){
				  stage.removeChild(toolTips);
			  }
			  stage.removeEventListener(MouseEvent.MOUSE_MOVE,onMouseMove);
			  if(tweenMax){
				  tweenMax.kill();
				  toolTips.alpha=1;
			  }
		  }
		  
		  /**
		   * 根据需求可重写此方法,修改text属性将会触发此方法的调用。
		   * @param contain tips显示容器
		   * @param text 要显示的文件。
		   * 需要重写
		   */
		  protected function draw(contain:Sprite,content:*):void{
			  /*
			  while(contain.numChildren>0){
				  contain.removeChildAt(0);
			  }
			  var t:TextField=new TextField();
			 // t.multiline=true;
			  t.height=20;
             
			  t.textColor=0xffffff;//微软雅黑
			  t.htmlText=text;
			  t.x=8;
			  t.y=5;
			  t.width=t.textWidth+10;
			  contain.addChild(t);
			  contain.graphics.clear();
			  contain.graphics.lineStyle(1,0x0,1,true);
			  contain.graphics.beginFill(0x966034,0.8);
			  contain.graphics.drawRoundRect(0,0,t.width+8,28,8,8); //.drawRect(0,0,t.width,20);
			  contain.graphics.endFill();
			  */
		  }

		  /**
		   * 文本内容，对文本修改将会重绘。
		   * @return
		   *
		   */
		  public function get text():*
		  {
			  return _content;
		  }
		  
		  public function set text(value:*):void
		  {
			  if(value==null || value==""){
				  _visible=false;
			  }else{
				  _visible=true;
			  }
			  _content= value;
			  if(toolTips==null){
				  toolTips=new Sprite();
			  }
			  if(target==null) return ;
			  if( !target.stage || !target.hitTestPoint( target.stage.mouseX , target.stage.mouseY )  )
			  {
				  return ; 
			  }
			  if(toolTips && toolTips.parent){
				  draw(toolTips,value);
			  }
		  }
		  
	}
}